package models

import (
	"cgs-server/server/cgs/app/models/filter"
	"cgs-server/server/model"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo/options"
)

// FilterParam 过滤参数
type FilterParam struct {
	// Id 过滤条件Id
	Id primitive.ObjectID `json:"id" bson:"id"`
	// 表格 id （新）
	WorksheetId string `json:"worksheetId" bson:"worksheetId" validate:"required"`
	// 过滤条件
	Filters filter.Filters `json:"filters,omitempty" bson:"filters,omitempty"`
	// 页码
	PageNo *int64 `json:"pageNo,omitempty" bson:"pageNo,omitempty"`
	// 行数
	PageSize *int64 `json:"pageSize,omitempty" bson:"pageSize,omitempty"`
	// 排序字段
	SortField string `json:"sortField,omitempty" bson:"sortField,omitempty"`
	// 是否升序
	IsAsc bool `json:"isAsc,omitempty" bson:"isAsc,omitempty"`
	// 搜索文本
	Keywords string `json:"keywords,omitempty" bson:"keywords,omitempty"`

	// 返回的数据格式，针对列表使用
	Format *int `json:"format" bson:"format"`

	// RelationRowId 关联表RowID
	RelationRowId string `json:"relationRowId,omitempty" bson:"relationRowId,omitempty"`

	model.BaseModel
}

func (f FilterParam) ResolveFilterParam(fields Fields) bson.M {
	filter1 := f.Filters.ResolveFilterParam()
	result := bson.M{}

	if f.Keywords != "" {
		arr := bson.A{}
		for _, field := range fields {
			arr = append(arr, bson.M{
				field.DataType.FilterKey(field.Name): bson.M{"$regex": f.Keywords},
			})
		}
		keyFilter := bson.M{
			"$or": arr,
		}

		result = bson.M{
			"$and": bson.A{
				filter1,
				keyFilter,
			},
		}

		//if filter1["$or"] != nil {
		//	if or, ok := filter1["$or"].(primitive.A); ok {
		//		or = append(or, arr...)
		//		result["$or"] = or
		//	}
		//} else {
		//	arr = append(arr, filter1)
		//	result["$or"] = arr
		//}
	} else {
		result = filter1
	}

	// 关联表rowId
	if f.RelationRowId != "" {
		result["relationRowId"] = f.RelationRowId
	}

	return result
}

func (f FilterParam) ResolveOptions() *options.FindOptions {
	opts := options.FindOptions{}
	isAsc := -1
	if f.IsAsc {
		isAsc = 1
	}
	if f.SortField != "" {
		opts.SetSort(bson.M{
			f.SortField: isAsc,
		})
	}

	return &opts
}
